// License Notification
//======================================================
// Copyright (c) 2010 Channel Intelligence Inc.
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// ======================================================




using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using CIP4.Common;

namespace CIP4.DataProvider.Sql
{
    delegate SqlConnection GetAndOpenConnectionDelegate(LoggerDelegate logger);

    class CIP4FileStream: Stream
    {
        private MemoryStream _StreamBase;

        public MemoryStream StreamBase
        {
            get 
            {
                if (_StreamBase == null)
                    GetData();
                return _StreamBase; 
            }
        }

        Guid CollectionId { get; set; }

        string ExternalID { get; set; }

        string Path { get; set; }

        GetAndOpenConnectionDelegate GetAndOpenConnection;

        LoggerDelegate Logger;

        public CIP4FileStream(Guid collectionId, string externalID, string path, GetAndOpenConnectionDelegate getAndOpenConnection, LoggerDelegate logger)
        {
            CollectionId = collectionId;
            ExternalID = externalID;
            Path = path;
            GetAndOpenConnection = getAndOpenConnection;
            Logger = logger;
        }

        private void GetData()
        {
            using (SqlConnection connection = GetAndOpenConnection(Logger))
            {
                using (SqlCommand command = connection.CreateCommand())
                {
                    command.CommandText = "SELECT [Data] FROM [BinaryData] WHERE [CollectionID] = @CollectionID AND [ExternalID] = @ExternalID AND [Path] = @Path";
                    command.CommandType = System.Data.CommandType.Text;

                    command.Parameters.AddWithValue("@CollectionID", CollectionId);
                    command.Parameters.AddWithValue("@ExternalID", ExternalID);
                    command.Parameters.AddWithValue("@Path", Path);

                    using (SqlDataReader reader = command.ExecuteReader())
                    {
                        reader.Read();

                        byte[] data = (byte[])reader["Data"];

                        _StreamBase = new MemoryStream(data);

                        connection.Close();
                    }
                }
            }
        }

        public override bool CanRead
        {
            get { return true; }
        }

        public override bool CanSeek
        {
            get { return true; }
        }

        public override bool CanWrite
        {
            get { return false; }
        }

        public override void Flush()
        {
            StreamBase.Flush();
        }

        public override long Length
        {
            get { return StreamBase == null? 0 :StreamBase.Length; }
        }

        public override long Position
        {
            get
            {
                return StreamBase == null? 0 : StreamBase.Position;
            }
            set
            {
                if (StreamBase != null)
                    StreamBase.Position = value;
            }
        }

        public override int Read(byte[] buffer, int offset, int count)
        {
            return StreamBase.Read(buffer, offset, count);
        }

        public override long Seek(long offset, SeekOrigin origin)
        {
            return StreamBase.Seek(offset, origin);
        }

        public override void SetLength(long value)
        {
            StreamBase.SetLength(value);
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            StreamBase.Write(buffer, offset, count);
        }
    }
}
